package com.misc.tunewsreader;

import java.util.ArrayList;

import android.content.Context;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.Filter;
import android.widget.TextView;

public class SectionListAdapterCheck extends ArrayAdapter<ListItem> {

    private ArrayList<ListItem> items;
    private ArrayList<ListItem> items_orig = null;
    private LayoutInflater vi;
    private ArrayList<Boolean> checked_orig = null;
    private ArrayList<Boolean> checked;
    private Filter filter = null;
    private final Object lock = new Object();

    public SectionListAdapterCheck(Context context, ArrayList<ListItem> items) {
	super(context, 0, items);
	this.items = items;
	checked = new ArrayList<Boolean>();
	for (int i = 0; i < items.size(); i++) {
	    checked.add(false);
	}

	vi = (LayoutInflater) context
		.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
	View view = convertView;

	final ListItem item = items.get(position);
	if (item != null) {
	    if (item.isSection()) {
		ListSection si = (ListSection) item;
		view = vi.inflate(R.layout.list_section, null);

		view.setOnClickListener(null);
		view.setOnLongClickListener(null);
		view.setLongClickable(false);

		final TextView sectionView = (TextView) view
			.findViewById(R.id.list_section_text);
		sectionView.setText(si.getTitle());
	    } else {
		ListEntry ei = (ListEntry) item;
		view = vi.inflate(R.layout.list_entry_check, null);
		final CheckedTextView title = (CheckedTextView) view
			.findViewById(R.id.list_item_check_title);

		final TextView full_name = (TextView) view
			.findViewById(R.id.list_item_check_full_text);

		if (title != null) {
		    title.setText(ei.title);
		    title.setChecked(checked.get(position));
		}
		if (full_name != null)
		    full_name.setText(ei.full_name);

	    }
	}
	return view;
    }

    public void setChecked(int position, boolean value) {
	checked.set(position, value);
    }

    public Filter getFilter() {
	if (filter == null) {
	    filter = new ArrayFilter();
	}
	return filter;
    }

    public ListItem getItem(int position) {
	return items.get(position);
    }

    public int getPosition(ListItem item) {
	return items.indexOf(item);
    }

    public long getItemId(int position) {
	return position;
    }

    public int getCount() {
	return items.size();
    }

    private class ArrayFilter extends Filter {
	@Override
	protected FilterResults performFiltering(CharSequence prefix) {
	    FilterResults results = new FilterResults();

	    // save unfiltered items in items_orig (first time filter is
	    // applied)
	    if (items_orig == null) {
		synchronized (lock) {
		    items_orig = new ArrayList<ListItem>(items);
		    checked_orig = new ArrayList<Boolean>(checked);
		}
	    }

	    // remove filter
	    if (prefix == null || prefix.length() == 0) {
		ArrayList<ListItem> list;
		ArrayList<Boolean> new_check;
		synchronized (lock) {
		    list = new ArrayList<ListItem>(items_orig);
		    new_check = new ArrayList<Boolean>(checked_orig);
		}
		results.values = new Pair<ArrayList<ListItem>, ArrayList<Boolean>>(
			list, new_check);
		results.count = list.size();
	    } else {
		// start filtering
		ArrayList<ListItem> new_values = new ArrayList<ListItem>();
		ArrayList<Boolean> new_check = new ArrayList<Boolean>();
		for (int i = 0; i < items_orig.size(); i++) {
		    if (items_orig.get(i).matchesFilter(prefix)) {
			if (new_values.size() > 0) {
			    ListItem last = new_values
				    .get(new_values.size() - 1);
			    // if last was section header and this is
			    // section header,
			    // remove last section header (because category
			    // is empty)
			    if (last.isSection()
				    && items_orig.get(i).isSection()) {
				synchronized (lock) {
				    new_values.remove(new_values.size() - 1);
				    new_check.remove(new_check.size() - 1);
				}
			    }
			}
			synchronized (lock) {
			    new_values.add(items_orig.get(i));
			    new_check.add(checked_orig.get(i));
			}
		    }
		}
		// if last item is section header, remove it
		if (new_values.size() > 0) {
		    if (new_values.get(new_values.size() - 1).isSection()) {
			synchronized (lock) {
			    new_values.remove(new_values.size() - 1);
			    new_check.remove(new_check.size() - 1);
			}
		    }
		}

		results.values = new Pair<ArrayList<ListItem>, ArrayList<Boolean>>(
			new_values, new_check);
		results.count = new_values.size();
	    }

	    return results;
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void publishResults(CharSequence constraint,
		FilterResults results) {
	    // apply filter -> save filtered results as new item list and notify
	    // the list view to update
	    Pair<ArrayList<ListItem>, ArrayList<Boolean>> res = (Pair<ArrayList<ListItem>, ArrayList<Boolean>>) results.values;
	    items = res.first;
	    checked = res.second;
	    if (results.count > 0) {
		notifyDataSetChanged();
	    } else {
		notifyDataSetInvalidated();
	    }
	}
    }

}
